/**
 * 
 */
package com.runningfox.logic;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.zip.GZIPInputStream;

import org.xmlpull.v1.XmlPullParser;

import android.util.Log;
import android.util.Xml;

import com.runningfox.humor.ProcessCallback;
import com.runningfox.model.Comment;
import com.runningfox.model.Joke;
import com.runningfox.model.ResultSet;
import com.runningfox.model.User;

/**
 * @author lhy
 * 
 */
public class Parser {
	static class t {

		public static final String JOKE = "joke";
		public static final String JOKENODE = "jokenode";
		public static final String BODY = "body";
		public static final String ID = "id";
		public static final String DATE = "date";
		public static final String LIKE = "like";
		public static final String DISLIKE = "dislike";
		public static final String OLD = "dislike";
		public static final String USER = "user";
		public static final String USERNAME = "username";
		public static final String USERID = "userid";
		public static final String TITLE = "title";
		public static final String TAG = "tag";
		public static final String URL = "url";
		public static final String CONTENTVERSION = "contentversion";
		public static final String PAGE = "page";
		public static final String DIRTY = "dirty";
		public static final String SIZE = "size";
		public static final String COMMENTCNT = "commentcnt";

		public static final String COMMENT = "comment";
		public static final String NAME = "name";

		public static final String IMEI = "imei";
		public static final String EMAIL = "email";
		public static final String GENDER = "gender";

		public static final String TIP="tip";
		public static final String RES = "res";
	}

	/**
	 * 
	 */
	public static final String xml_prefix = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
	// 2009-12-17 09:04:38.445318
	public static SimpleDateFormat dateFormat = new SimpleDateFormat(
			"yyyy-MM-dd hh:MM:ss");

	/**
	 * 判断流类型，如果是压缩流，则解压；如果不是压缩流，不做操作
	 * 
	 * @param is
	 * @return
	 */
	static InputStream getStream(InputStream is) {
		InputStream rtn_is = null;
		try {
			rtn_is = new GZIPInputStream(is);
			// String str = StreamToolBox.loadStringFromStream(rtn_is);
			// Log.v("gzipxml", str);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			// 不是压缩格式的流
			rtn_is = is;
			try {
				String str = StreamToolBox.loadStringFromStream(rtn_is);
				if (!str.startsWith(xml_prefix)) {
					// 如果字符串不是以xml文档开头，补齐
					int index = str.indexOf("<root>");
					if(index<0){
						index=str.indexOf("<ROOT>");
					}
					str = xml_prefix + str.substring(index);
				}
				ByteArrayInputStream tis = new ByteArrayInputStream(str
						.getBytes("utf-8"));
				Log.v("xml", str);
				return tis;
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}

		} catch (Exception e) {
			e.printStackTrace();
			rtn_is = is;
		}
		return rtn_is;
	}

	public static ResultSet parse(InputStream is, ProcessCallback callback) {
		if (callback != null) {
			callback.onParsing();
		}
		ResultSet res = new ResultSet();
		ArrayList<Joke> jokeList = new ArrayList<Joke>();
		ArrayList<Comment> commentList = new ArrayList<Comment>();
		Object cur = null;
		XmlPullParser parser = Xml.newPullParser();
		try {
			// auto-detect the encoding from the stream
			parser.setInput(getStream(is), null);
			// parser.setInput(is, null);
			int eventType = parser.getEventType();
			boolean done = false;
			String name = null;
			while (eventType != XmlPullParser.END_DOCUMENT && !done) {
				switch (eventType) {
				case XmlPullParser.START_DOCUMENT:
					Log.v("parser", "XmlPullParser.START_DOCUMENT");
					break;
				case XmlPullParser.END_DOCUMENT:
					done = true;
					break;
				case XmlPullParser.START_TAG: {
					name = parser.getName();
					if (name != null && name.equalsIgnoreCase(t.JOKENODE)) {
						cur = new Joke();
					}
					if (name != null && name.equalsIgnoreCase(t.COMMENT)) {
						cur = new Comment();
					}
					if (name != null && name.equalsIgnoreCase(t.USER)) {
						cur = new User();
					}
					break;
				}
				case XmlPullParser.END_TAG: {
					name = parser.getName();
					if (name != null) {
						if (name.equalsIgnoreCase(t.JOKENODE) && cur != null) {
							jokeList.add((Joke) cur);
						}
						if (name.equalsIgnoreCase(t.COMMENT) && cur != null) {
							commentList.add((Comment) cur);
						}
						name = null;
					}
					break;
				}
				case XmlPullParser.TEXT: {
					String text = parser.getText();
					if (name != null && name.equalsIgnoreCase(t.SIZE)) {
						res.size = Integer.valueOf(text.trim());
					} else if (name != null && name.equalsIgnoreCase(t.USER)) {
						res.user = new User();
					} else if (name != null && name.equalsIgnoreCase(t.ID)
							&& res.user != null) {
						res.user.id = text.trim();
					} else if (name != null && name.equalsIgnoreCase(t.NAME)
							&& res.user != null) {
						res.user.name = text.trim();
					} else if (name != null && name.equalsIgnoreCase(t.IMEI)
							&& res.user != null) {
						res.user.imei = text.trim();
					} else if (name != null && name.equalsIgnoreCase(t.GENDER)
							&& res.user != null) {
						res.user.gender = text.trim();
					} else if (name != null && name.equalsIgnoreCase(t.DATE)
							&& res.user != null) {
						res.user.datestr = text.trim();
					} else if (name != null && name.equalsIgnoreCase(t.RES)) {
						res.res = text.trim();
					} else if (cur != null && cur instanceof Joke) {
						Joke n = (Joke) cur;
						if (name != null) {
							if (name.equalsIgnoreCase(t.TITLE)) {
								n.title = text;
							} else if (name.equalsIgnoreCase(t.COMMENTCNT)) {
								n.comment = text.trim();
							} else if (name.equalsIgnoreCase(t.DATE)) {
								// 2009-12-17 09:04:38.445318
								n.dateStr = text;
								int dotIndex = text.lastIndexOf('.');
								if (dotIndex > 0) {
									text = text.substring(0, dotIndex);
								}
								try {
									n.datetime = dateFormat.parse(text);
								} catch (Exception e) {
									n.datetime = new Date();
								}
							} else if (name.equalsIgnoreCase(t.DISLIKE)) {
								// n.dislike = text;
							} else if (name.equalsIgnoreCase(t.ID)) {
								try {
									n.id = Integer.parseInt(text.trim());
								} catch (Exception e) {
									n.id = -1;
									e.printStackTrace();
								}
							} else if (name.equalsIgnoreCase(t.LIKE)) {
								n.like = text;
							} else if (name.equalsIgnoreCase(t.OLD)) {
								// n.old = text;
							} else if (name.equalsIgnoreCase(t.USERNAME)) {
								n.user = text;
							} else if (name.equalsIgnoreCase(t.USERID)) {
								// n.userid = text;
							} else if (name.equalsIgnoreCase(t.TAG)) {
								n.tag = text;
							} else if (name.equalsIgnoreCase(t.URL)) {
								n.url = text;
							} else if (name.equalsIgnoreCase(t.CONTENTVERSION)) {
								res.contentVersion = Long
										.parseLong(text.trim());
							} else if (name.equalsIgnoreCase(t.BODY)) {
								n.body = text;
							} else if (name.equalsIgnoreCase(t.DIRTY)) {
								n.dirty = Integer.valueOf(text.trim());
							}
						}
					}
					if (name != null && name.equals(t.PAGE)) {
						res.page = text;
					}
					if (cur != null && cur instanceof Comment) {
						Comment comment = (Comment) cur;
						if (name != null) {
							if (name.equalsIgnoreCase(t.ID)) {
								comment.id = Integer.parseInt(text);
							} else if (name.equalsIgnoreCase(t.BODY)) {
								comment.body = text;
							} else if (name.equalsIgnoreCase(t.DATE)) {
								comment.dateStr = text;
							} else if (name.equalsIgnoreCase(t.NAME)) {
								comment.name = text;
							}
						}
					}
					break;
				}
				}
				eventType = parser.next();
			}
		} catch (Exception e) {
			if (callback != null) {
				callback.onParseFail();
			}
			e.printStackTrace();
			return null;
		}
		res.jokeList = jokeList;
		res.commentList = commentList;
		return res;
	}

}
